package com.neo.tiny.business.queue.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.neo.tiny.business.queue.entity.QueueDO;
import com.neo.tiny.business.queue.entity.QueueWindowRelationDO;
import com.neo.tiny.business.queue.service.QueueService;
import com.neo.tiny.business.queue.service.QueueWindowRelationService;
import com.neo.tiny.business.queue.vo.queue.QueueCreateReqVO;
import com.neo.tiny.business.queue.vo.queue.QueuePageReqVO;
import com.neo.tiny.business.queue.vo.queue.QueueResVO;
import com.neo.tiny.business.queue.vo.queue.QueueUpdateReqVO;
import com.neo.tiny.business.queue.vo.queuewindow.QueueWindowRelationCreateReqVO;
import com.neo.tiny.common.common.ResResult;
import com.neo.tiny.common.util.CommonDoTransfer;
import com.neo.tiny.resolver.CommonPage;
import com.neo.tiny.util.MyBatisUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description: 队列
 * @Author: yqz
 * @CreateDate: 2022-10-27 22:48:54
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/queue/business-queue")
@Api(tags = "队列管理")
public class QueueController {

    private final QueueService queueService;

    private final QueueWindowRelationService queueWindowRelationService;

    /**
     * 分页查询
     *
     * @param req 队列
     * @return
     */
    @ApiOperation("分页查询")
    @GetMapping("/page")
    public ResResult<IPage<QueueResVO>> getQueuePage(@Valid QueuePageReqVO req) {

        LambdaQueryWrapper<QueueDO> wrapper = new LambdaQueryWrapper<QueueDO>()
                .like(StrUtil.isNotBlank(req.getQueueName()), QueueDO::getQueueName, req.getQueueName())
                .or()
                .like(StrUtil.isNotBlank(req.getQueueKey()), QueueDO::getQueueKey, req.getQueueKey())
                .orderByAsc(QueueDO::getSortOrder);

        return ResResult.success(CommonPage.restPage(queueService.page(MyBatisUtils.buildPage(req), wrapper), QueueResVO.class));
    }


    /**
     * 通过id查询队列
     *
     * @param queueId id
     * @return ResResult
     */
    @ApiOperation("通过id查询")
    @GetMapping("/{queueId}")
    public ResResult<QueueResVO> getById(@PathVariable("queueId") Long queueId) {
        return ResResult.success(BeanUtil.copyProperties(queueService.getById(queueId), QueueResVO.class));
    }

    /**
     * 新增队列
     *
     * @param queueCreateReqVO 队列
     * @return ResResult
     */
    @ApiOperation("新增队列")
    @PostMapping("/create")
    public ResResult<Long> save(@Valid @RequestBody QueueCreateReqVO queueCreateReqVO) {
        checkQueueNameAndKey(null, queueCreateReqVO.getQueueName(), queueCreateReqVO.getQueueKey());
        QueueDO queue = BeanUtil.copyProperties(queueCreateReqVO, QueueDO.class);
        queueService.save(BeanUtil.copyProperties(queueCreateReqVO, QueueDO.class));

        return ResResult.success(queue.getQueueId());
    }

    /**
     * 校验队列名称、队列标识
     *
     * @param queueId   队列id
     * @param queueName 窗口号
     * @param queueKey  队列标识
     */
    public void checkQueueNameAndKey(Long queueId, String queueName, String queueKey) {
        long count = queueService.count(new LambdaQueryWrapper<QueueDO>()
                .eq(StrUtil.isNotBlank(queueName), QueueDO::getQueueName, queueName)
                .ne(!Objects.isNull(queueId), QueueDO::getQueueId, queueId));
        Assert.isTrue(count <= 0, "队列名称重复");
        long countKey = queueService.count(new LambdaQueryWrapper<QueueDO>()
                .eq(StrUtil.isNotBlank(queueKey), QueueDO::getQueueKey, queueKey)
                .ne(!Objects.isNull(queueId), QueueDO::getQueueId, queueId));
        Assert.isTrue(countKey <= 0, "队列标识重复");

    }

    /**
     * 修改队列
     *
     * @param queueUpdateReqVO 队列
     * @return ResResult
     */
    @ApiOperation("修改队列")
    @PutMapping("/update")
    public ResResult<Boolean> updateById(@Valid @RequestBody QueueUpdateReqVO queueUpdateReqVO) {
        checkQueueNameAndKey(queueUpdateReqVO.getQueueId(), queueUpdateReqVO.getQueueName(), queueUpdateReqVO.getQueueKey());

        queueService.updateById(BeanUtil.copyProperties(queueUpdateReqVO, QueueDO.class));
        return ResResult.success(true);
    }

    /**
     * 通过id删除队列
     *
     * @param queueId id
     * @return R
     */
    @ApiOperation("通过id删除队列")
    @DeleteMapping("/{queueId}")
    public ResResult<Boolean> removeById(@PathVariable Long queueId) {
        return ResResult.success(queueService.removeById(queueId));
    }

    @ApiOperation("查询队列已绑定的窗口")
    @GetMapping("/list-queue-win/{queueId}")
    public ResResult<Set<Long>> listQueueWithWin(@PathVariable("queueId") Long queueId) {

        List<QueueWindowRelationDO> list = queueWindowRelationService.list(new LambdaQueryWrapper<QueueWindowRelationDO>()
                .eq(QueueWindowRelationDO::getQueueId, queueId));

        Set<Long> windowIds = list.stream().map(QueueWindowRelationDO::getWindowId)
                .collect(Collectors.toSet());
        return ResResult.success(windowIds);
    }

    @ApiOperation("绑定队列与窗口")
    @PostMapping("/bind-queue-window")
    public ResResult<Boolean> bindQueueWithWindow(@Valid @RequestBody QueueWindowRelationCreateReqVO req) {

        log.info("绑定队列与窗口入参：{}", req);

        return ResResult.success(queueWindowRelationService.bindQueueWithWindow(req.getQueueId(), req.getWindowIds()));
    }

    @ApiOperation("查询所有队列")
    @GetMapping("/list")
    public ResResult<List<QueueResVO>> listAllQueue() {

        List<QueueDO> list = queueService.list();

        return ResResult.success(CommonDoTransfer.transfer(list, QueueResVO.class));
    }

}
